home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / transpor / ifmail23.z / ifmail23 / ifmail / ifgate / message.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-09  |  8.2 KB  |  346 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <time.h>
  6. #include "xutil.h"
  7. #include "lutil.h"
  8. #include "ftn.h"
  9. #include "ftnmsg.h"
  10. #include "rfcmsg.h"
  11. #include "config.h"
  12. #include "bwrite.h"
  13. #include "falists.h"
  14.  
  15. #define MAXMSGSIZE 8192
  16. #define MSGTYPE 2
  17. #define MAXSEEN 70
  18. #define MAXPATH 73
  19.  
  20. extern int newsmode;
  21. extern char *version;
  22. extern faddr *bestaka;
  23.  
  24. #ifdef HAS_NDBM_H
  25. extern char *idlookup(char *);
  26. #endif
  27. extern char *bgets(char *,int,FILE *);
  28. extern long sequencer(void);
  29.  
  30. int needputrfc(msg)
  31. rfcmsg *msg;
  32. {
  33.     faddr *ta;
  34.  
  35.     /* 0-junk, 1-kludge, 2-pass */
  36.  
  37.     if (!strcasecmp(msg->key,"X-UUCP-From")) return 0;
  38.     if (!strcasecmp(msg->key,"X-Body-Start")) return 0;
  39.     if (!strncasecmp(msg->key,"X-FTN-",6)) return 0;
  40.     if (!strcasecmp(msg->key,"Newsgroups")) return 0;
  41.     if (!strcasecmp(msg->key,"Xref")) return 0;
  42.     if (!strcasecmp(msg->key,"Return-Receipt-To")) return 1;
  43.     if (!strcasecmp(msg->key,"Received")) return newsmode?0:2;
  44.     if (!strcasecmp(msg->key,"From"))
  45.     {
  46.         if ((ta=parsefaddr(msg->val)))
  47.         {
  48.             tidy_faddr(ta);
  49.             return 0;
  50.         }
  51.         else return 2;
  52.     }
  53.     if (!strcasecmp(msg->key,"To"))
  54.     {
  55.         if (newsmode) return 0;
  56.         if ((ta=parsefaddr(msg->val)))
  57.         {
  58.             tidy_faddr(ta);
  59.             return 0;
  60.         }
  61.         else return 2;
  62.     }
  63.     if (!strcasecmp(msg->key,"Reply-To")) return 2;
  64.     if (!strcasecmp(msg->key,"Lines")) return 0;
  65.     if (!strcasecmp(msg->key,"Date")) return 0;
  66.     if (!strcasecmp(msg->key,"Subject")) 
  67.     {
  68.         if (strlen(msg->val) > MAXSUBJ) return 2;
  69.         else return 0;
  70.     }
  71.     if (!strcasecmp(msg->key,"Organization")) return 1; 
  72.     if (!strcasecmp(msg->key,"Comment-To")) return 0;
  73.     if (!strcasecmp(msg->key,"X-Comment-To")) return 0;
  74.     if (!strcasecmp(msg->key,"Keywords")) return 2;
  75.     if (!strcasecmp(msg->key,"Summary")) return 2;
  76.     /*if (!strcasecmp(msg->key,"")) return ;*/
  77.     return 1;
  78. }
  79.  
  80. extern char *months[];
  81. static char *weekday[] = {
  82. "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
  83. };
  84.  
  85. char *viadate(void)
  86. {
  87.     static char buf[64];
  88.     time_t t;
  89.     struct tm *ptm;
  90.  
  91.     time(&t);
  92.     ptm=localtime(&t);
  93.     sprintf(buf,"%s %s %d %d at %02d:%02d",
  94.         weekday[ptm->tm_wday],months[ptm->tm_mon],
  95.         ptm->tm_mday,ptm->tm_year+1900,ptm->tm_hour,ptm->tm_min);
  96.     return buf;
  97. }
  98.  
  99. int putmessage(msg,fmsg,fp,pkt,sbl)
  100. rfcmsg *msg;
  101. ftnmsg *fmsg;
  102. FILE *fp,*pkt;
  103. fa_list **sbl;
  104. {
  105.     char buf[BUFSIZ],*p,*q,subjext[16],newsubj[MAXSUBJ+1];
  106.     rfcmsg *tmp;
  107.     int rfcheaders;
  108.     int needsplit,datasize,splitpart;
  109.     fa_list *tmpl;
  110.     fa_list *ptl=NULL;
  111.     int seenlen;
  112.     int oldnet;
  113.     int i;
  114.     char sbe[16];
  115.  
  116.     debug(3,"putmessage from %s",ascfnode(fmsg->from,0x7f));
  117.     debug(3,"putmessage   to %s",ascfnode(fmsg->to,0x7f));
  118.     debug(3,"putmessage subj %s",fmsg->subj);
  119.     debug(3,"putmessage flags %04x",fmsg->flags);
  120.     debug(3,"putmessage msgid %s",fmsg->msgid);
  121.     debug(3,"putmessage reply %s",fmsg->reply);
  122.     debug(3,"putmessage date %s",fmsg->date);
  123.  
  124.     needsplit=0;
  125.     splitpart=0;
  126.     do
  127.     {
  128.         datasize=14;
  129.  
  130.         iwrite(MSGTYPE,         pkt);
  131.         iwrite(fmsg->from->node,pkt);
  132.         iwrite(fmsg->to->node,  pkt);
  133.         iwrite(fmsg->from->net, pkt);
  134.         iwrite(fmsg->to->net,   pkt);
  135.         iwrite(fmsg->flags,     pkt);
  136.         iwrite(0,               pkt);
  137.         awrite(fmsg->date,      pkt);
  138.         awrite(fmsg->to->name,  pkt);
  139.         awrite(fmsg->from->name,pkt);
  140.         if (splitpart)
  141.         {
  142.             sprintf(subjext,"...part %d",splitpart+1);
  143.             strcpy(newsubj,fmsg->subj);
  144.             if ((int)strlen(newsubj) > (int)(MAXSUBJ - strlen(subjext)))
  145.                 newsubj[MAXSUBJ - strlen(subjext)] = '\0';
  146.             strcat(newsubj,subjext);
  147.             awrite(newsubj,pkt);
  148.         }
  149.         else awrite(fmsg->subj,pkt);
  150.  
  151.         if (fmsg->area) fprintf(pkt,"AREA:%s\r",fmsg->area);
  152.  
  153.         if (!newsmode)
  154.         {
  155.             if (fmsg->to->point)
  156.                 fprintf(pkt,"\1TOPT %u\r",fmsg->to->point);
  157.             if (fmsg->from->point)
  158.                 fprintf(pkt,"\1FMPT %u\r",fmsg->from->point);
  159. #ifndef FORCEINTL
  160.             if (fmsg->to->zone != fmsg->from->zone)
  161. #endif
  162.                 fprintf(pkt,"\1INTL %u:%u/%u %u:%u/%u\r",
  163.                     fmsg->to->zone,
  164.                     fmsg->to->net,
  165.                     fmsg->to->node,
  166.                     fmsg->from->zone,
  167.                     fmsg->from->net,
  168.                     fmsg->from->node
  169.                     );
  170.         }
  171.         if ((!needsplit) && fmsg->msgid) 
  172.             fprintf(pkt,"\1MSGID: %s\r",fmsg->msgid);
  173.         else
  174.             fprintf(pkt,"\1MSGID: %s %08lx \r",
  175.                 ascfnode(bestaka,0x1f),
  176.                 sequencer());
  177.         if (fmsg->reply) fprintf(pkt,"\1REPLY: %s\r",fmsg->reply);
  178.  
  179.         for (tmp=msg;tmp;tmp=tmp->next) 
  180.         if (!strncmp(tmp->key,"X-FTN-",6) &&
  181.             strcasecmp(tmp->key,"X-FTN-AREA") &&
  182.             strcasecmp(tmp->key,"X-FTN-SEEN-BY") &&
  183.             strcasecmp(tmp->key,"X-FTN-PATH") &&
  184.             strcasecmp(tmp->key,"X-FTN-Via"))
  185.             if (strcasecmp(tmp->key,"X-FTN-KLUDGE") == 0)
  186.             {
  187.                 datasize += strlen(tmp->val);
  188.                 fprintf(pkt,"\1");
  189.         /* we should have restored the original string here... */
  190.                 kwrite(tmp->val,pkt);
  191.             }
  192.             else
  193.             {
  194.                 datasize += strlen(tmp->key)+strlen(tmp->val);
  195.                 fprintf(pkt,"\1%s:",tmp->key+6);
  196.                 kwrite(tmp->val,pkt);
  197.             }
  198.  
  199.         rfcheaders=0;
  200.         for (tmp=msg;tmp;tmp=tmp->next) if (needputrfc(tmp) == 1)
  201.         {
  202.             rfcheaders++;
  203.             datasize += strlen(tmp->key)+strlen(tmp->val);
  204.             fprintf(pkt,"\1RFC-%s:",tmp->key);
  205.             kwrite(tmp->val,pkt);
  206.         }
  207.         for (tmp=msg;tmp;tmp=tmp->next) if (needputrfc(tmp) == 2)
  208.         {
  209.             rfcheaders++;
  210.             datasize += strlen(tmp->key)+strlen(tmp->val);
  211.             fprintf(pkt,"%s:",tmp->key);
  212.             cwrite(tmp->val,pkt);
  213.         }
  214.         if (rfcheaders) cwrite("\n",pkt);
  215.  
  216.         if (needsplit)
  217.         {
  218.             fprintf(pkt," * Continuation %d of a splitted message *\r\r",
  219.                 splitpart);
  220.             needsplit=0;
  221.         }
  222.         else if ((p=hdr("X-Body-Start",msg))) 
  223.         {
  224.             datasize += strlen(p);
  225.             cwrite(p,pkt);
  226.         }
  227.         while (!(needsplit=(datasize > MAXMSGSIZE)) &&
  228.             (bgets(buf,sizeof(buf)-1,fp)))
  229.         {
  230.             debug(19,"putmessage body %s",buf);
  231.             datasize += strlen(buf);
  232.             cwrite(buf,pkt);
  233.         }
  234.         if (needsplit)
  235.         {
  236.             fprintf(pkt,"\r * Message split, to be continued *\r");
  237.             splitpart++;
  238.         }
  239.             
  240.         if (newsmode)
  241.         {
  242.             fprintf(pkt,"\r--- ifmail v.%s",version);
  243.             fprintf(pkt,"\r * Origin: "); /* strlen=11 */
  244.             p=ascfnode(fmsg->from,0x1f);
  245.             i=79-11-3-strlen(p);
  246.             if (strlen(fmsg->origin) > i) fmsg->origin[i]='\0';
  247.             cwrite(fmsg->origin ? fmsg->origin : "Unknown",pkt);
  248.             fprintf(pkt," (%s)",p);
  249.  
  250.             for (tmpl=whoami;tmpl;tmpl=tmpl->next)
  251.             if ((tmpl->addr->point == 0) &&
  252.                 ((bestaka->domain == NULL) ||
  253.                  (tmpl->addr->domain == NULL) ||
  254.                  (strcasecmp(bestaka->domain,
  255.                     tmpl->addr->domain) == 0)) &&
  256.                 (bestaka->zone == tmpl->addr->zone))
  257.                 fill_list(sbl,ascfnode(tmpl->addr,0x06));
  258. #ifdef HAS_NDBM_H
  259.             if ((p=hdr("Message-ID",msg)))
  260.             {
  261.                 while (isspace(*p)) p++;
  262.                 q=xstrcpy(p);
  263.                 if (*(p=q+strlen(q)-1) == '\n') *(p--)='\0';
  264.                 while (isspace(*p)) *(p--)='\0';
  265.                 fill_list(sbl,idlookup(q));
  266.                 free(q);
  267.             }
  268. #endif
  269.             sort_list(sbl);
  270.             seenlen=MAXSEEN+1;
  271.             /* ensure it will not match for the first entry */
  272.             oldnet=(*sbl)->addr->net-1;
  273.             for (tmpl=*sbl;tmpl;tmpl=tmpl->next)
  274.             {
  275.                 if (tmpl->addr->net == oldnet)
  276.                     sprintf(sbe," %u",tmpl->addr->node);
  277.                 else
  278.                     sprintf(sbe," %u/%u",tmpl->addr->net,
  279.                             tmpl->addr->node);
  280.                 oldnet=tmpl->addr->net;
  281.                 seenlen+=strlen(sbe);
  282.                 if (seenlen > MAXSEEN)
  283.                 {
  284.                     seenlen=0;
  285.                     fprintf(pkt,"\rSEEN-BY:");
  286.                     sprintf(sbe," %u/%u",tmpl->addr->net,
  287.                             tmpl->addr->node);
  288.                     seenlen=strlen(sbe);
  289.                 }
  290.                 fprintf(pkt,"%s",sbe);
  291.             }
  292.  
  293.             for (tmp=msg;tmp;tmp=tmp->next) 
  294.             if (!strcasecmp(tmp->key,"X-FTN-PATH"))
  295.             {
  296.                 fill_path(&ptl,tmp->val);
  297.             }
  298.             sprintf(sbe,"%u/%u",bestaka->net,
  299.                 bestaka->node);
  300.             fill_path(&ptl,sbe);
  301.             uniq_list(&ptl);
  302.             seenlen=MAXPATH+1;
  303.             /* ensure it will not match for the first entry */
  304.             oldnet=ptl->addr->net-1;
  305.             for (tmpl=ptl;tmpl;tmpl=tmpl->next)
  306.             {
  307.                 if (tmpl->addr->net == oldnet)
  308.                     sprintf(sbe," %u",tmpl->addr->node);
  309.                 else
  310.                     sprintf(sbe," %u/%u",tmpl->addr->net,
  311.                             tmpl->addr->node);
  312.                 oldnet=tmpl->addr->net;
  313.                 seenlen+=strlen(sbe);
  314.                 if (seenlen > MAXPATH)
  315.                 {
  316.                     seenlen=0;
  317.                     fprintf(pkt,"\r\1PATH:");
  318.                     sprintf(sbe," %u/%u",tmpl->addr->net,
  319.                             tmpl->addr->node);
  320.                     seenlen=strlen(sbe);
  321.                 }
  322.                 fprintf(pkt,"%s",sbe);
  323.             }
  324.             fprintf(pkt,"\r");
  325.         }
  326.         else /* mail mode */
  327.         {
  328.             for (tmp=msg;tmp;tmp=tmp->next) 
  329.             if (!strcasecmp(tmp->key,"X-FTN-Via"))
  330.             {
  331.             datasize += strlen(tmp->key)+strlen(tmp->val);
  332.                 fprintf(pkt,"\1Via");
  333.                 kwrite(tmp->val,pkt);
  334.             }
  335.             fprintf(pkt,"\1Via ifmail %s, %s (%s)\r",
  336.                 ascfnode(bestaka,0x1f),
  337.                 viadate(),version);
  338.         }
  339.         awrite("",pkt); /* trailing zero byte */
  340.     }
  341.     while (needsplit);
  342.  
  343.     debug(3,"putmessage exiting...");
  344.     return 0;
  345. }
  346.